package com.whut.www.file_storage.activity;

import android.Manifest;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.StatFs;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.text.format.Formatter;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import com.whut.www.file_storage.R;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

public class MainActivity extends AppCompatActivity {
    private SharedPreferences mSharedPreferences;
    private final int REQUESTCODE_WRITE_EXTERNAL_STORAGE = 1;
    private boolean mShowed;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //internalStorage();
        externalStorage();
        Log.i("MainActivity", "---onCreate()--->" + "开始检查授权");
        //检查授权
        checkedPermission();
        Log.i("MainActivity", "---onCreate()--->" + "授权检查完毕");
        Log.i("MainActivity", "---onCreate()--->" + getMemoryInfo(Environment
                .getExternalStorageDirectory()));
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////
    //6.0动态授权
    //第一次申请授权被拒绝后再次申请授权,会带永不提示选项,用户勾选后再次申请权限不会出现授权对话框
    //当方法shouldShowRequestPermissionRationale(String permission)的型返回值为true时说明已经申请过该权限并被拒绝
    ////////////////////////////////////////////////////////////////////////////////////////////////////
    private void checkedPermission() {
        //检查是否获得该权限
        int granted = ContextCompat.checkSelfPermission(this, Manifest.permission
                .WRITE_EXTERNAL_STORAGE);
        if (granted != PackageManager.PERMISSION_GRANTED) {
            //未获得该权限--->申请权限
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission
                    .WRITE_EXTERNAL_STORAGE}, REQUESTCODE_WRITE_EXTERNAL_STORAGE);
            Log.i("MainActivity", "---checkedPermission()--->申请权限");
        } else {
            externalStorage();
            //已经获得该权限--->todo
            Log.i("MainActivity", "---checkedPermission()--->已经授权");
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                           @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        //检查是否申请过权限并且被拒绝
        mShowed = shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE);
        Log.i("MainActivity", "---checkedPermission()--->showed" + mShowed);
        switch (requestCode) {
            case REQUESTCODE_WRITE_EXTERNAL_STORAGE:
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    Toast.makeText(this, "授权成功", Toast.LENGTH_SHORT).show();
                    Log.i("MainActivity", "---onRequestPermissionsResult()--->" + "授权成功");
                    externalStorage();
                    //todo
                } else {
                    Toast.makeText(this, "授权失败", Toast.LENGTH_SHORT).show();
                    if (!mShowed) {
                        Toast.makeText(this, "申请过,并且被拒绝,永不显示,跳转到权限设置界面", Toast.LENGTH_SHORT).show();
                        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                        Uri uri = Uri.fromParts("package", getPackageName(), null);
                        intent.setData(uri);
                        //startActivityForResult(intent, 0);
                        return;
                    }
                    Log.i("MainActivity", "---onRequestPermissionsResult()--->" + "授权失败");
                }
                break;
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 0) {
            //resultCode始终为RESULT_CANCEL
            // 再次检查权限,用户可能未授权
            checkedPermission();
        }
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////
    //外部存储:
    //1.九大公有目录:Alarms、DCIM、Download、Movies、Music、Notifications、Pictures、Podcasts、Ringtones
    //2.私有cache目录、私有files目录(7大目录:Alarms、Movies、Music、Notifications、Pictures、Podcasts、Ringtones)
    //备注:点击app下的    清除缓存 私有cache目录会被删除;点击app下的  清除数据 私有cache目录、私有files目录都会被删除
    //备注:app卸载后，内部存储(/data/data/com.whut.www.file_storage目录下数据)、外部存储
    // (/storage/emulated/0/Android/data/com.whut.www.file_storage目录下数据)均被删除
    ////////////////////////////////////////////////////////////////////////////////////////////////
    private void externalStorage() {
        Log.i("MainActivity", "---externalStorage()--->");
        File externalDownload = Environment.getExternalStoragePublicDirectory("Download");
        Log.i("MainActivity", "---getExternalStoragePublicDirectory(Download)--->" +
                externalDownload.getAbsolutePath());
        //  /storage/emulated/0/Download

        File externalDownloadFile = new File(externalDownload, "7890");
        Toast.makeText(this, externalDownloadFile.mkdirs() + "", Toast.LENGTH_SHORT).show();

        File externalStorageDirectory = Environment.getExternalStorageDirectory();
        Log.i("MainActivity", "---getExternalStorageDirectory()--->" + externalStorageDirectory
                .getAbsolutePath());
        //  /storage/emulated/0   app在外部存储的数据一般存在此目录下

        File rootDirectory = Environment.getRootDirectory();
        Log.i("MainActivity", "---getRootDirectory()--->" + rootDirectory.getAbsolutePath());
        //  /system

        File dataDirectory = Environment.getDataDirectory();
        Log.i("MainActivity", "---getDataDirectory()--->" + dataDirectory.getAbsolutePath());
        //  /data

        File downloadCacheDirectory = Environment.getDownloadCacheDirectory();
        Log.i("MainActivity", "---getDownloadCacheDirectory()--->" + downloadCacheDirectory
                .getAbsolutePath());
        //  /data/cache

        //外部私有目录,不需要权限
        File externalCacheDir = getExternalCacheDir();
        Log.i("MainActivity", "---getExternalCacheDir()--->" + externalCacheDir.getAbsolutePath());
        //  /storage/emulated/0/Android/data/com.whut.www.file_storage/cache
        File externalFilesDir = getExternalFilesDir("Alarms");
        Log.i("MainActivity", "---getExternalFilesDir(Alarms)--->" + externalFilesDir
                .getAbsolutePath());
        Log.i("MainActivity", "------>" + getExternalFilesDir(null).getAbsolutePath());
        //  /storage/emulated/0/Android/data/com.whut.www.file_storage/files/Alarms


        File externalCacheDirFile = new File(externalCacheDir, "789");
        Toast.makeText(this, "" + externalCacheDirFile.mkdirs(), Toast.LENGTH_SHORT).show();
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////
    //内部存储:cache目录、files目录
    ////////////////////////////////////////////////////////////////////////////////////////////////
    private void internalStorage() {
        Log.i("MainActivity", "---internalStorage()--->");
        File cacheDir = getCacheDir();
        Log.i("MainActivity", "---getCacheDir()--->" + cacheDir.getAbsolutePath());
        //    /data/data/com.whut.www.file_storage/cache
        File filesDir = getFilesDir();
        Log.i("MainActivity", "---getFilesDir()--->" + filesDir.getAbsolutePath());
        //    /data/data/com.whut.www.file_storage/files
        File pictures = getFileStreamPath("Pictures");
        Log.i("MainActivity", "---getFileStreamPath(Pictures)--->" + pictures.getAbsolutePath());
        //  /data/data/com.whut.www.file_storage/files/Pictures
        if (!pictures.exists()) {
            boolean mkdirs = pictures.mkdirs();
            if (mkdirs) {
                Toast.makeText(this, "picture创建成功", Toast.LENGTH_SHORT).show();
            }
        }
        try {
            FileOutputStream fileOutputStream = openFileOutput("file.txt", MODE_WORLD_READABLE +
                    MODE_APPEND);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        //第一参数用于指定文件名称,不能包含路径分隔符“/”,如果文件不存在,Android会自动创建它。
        //创建的文件保存在/data/data/<package name>/files目录.
        //第二参数用于指定操作模式有四种模式:
        //  Context.MODE_PRIVATE为默认操作模式,代表该文件是私有数据,只能被应用本身访问
        //  Context.MODE_APPEND把新写入的内容追加到原文件末尾
        //  Context.MODE_WORLD_READABLE表示当前文件可以被其他应用读取
        //  Context.MODE_WORLD_WRITEABLE表示当前文件可以被其他应用写入
        //  可以使用"+"进行模式叠加
        String[] files = fileList();
        //返回files下所有的文件名
        boolean deleted = deleteFile("file.txt");
        //删除files下指定名称的文件
        File dir = getDir("custom.clvc", MODE_APPEND + MODE_WORLD_READABLE);
        //返回/data/data/包名/下的指定名称的文件夹File对象，如果该文件夹不存在则用指定名称创建一个新的文件夹。
    }


    /**
     * 根据路径获取内存状态
     *
     * @param path
     * @return
     */
    public String getMemoryInfo(File path) {
        // 获得一个磁盘状态对象
        StatFs stat = new StatFs(path.getPath());
        // 获得一个扇区的大小
        long blockSize = stat.getBlockSizeLong();
        // 获得扇区的总数
        long totalBlocks = stat.getBlockCountLong();
        // 获得可用的扇区数量
        long availableBlocks = stat.getAvailableBlocksLong();
        // 获得可用的扇区数量
        long freeBlocksLong = stat.getFreeBlocksLong();
        // 可用空间
        String freeMemory = Formatter.formatFileSize(this, freeBlocksLong * blockSize);
        // 总空间
        String totalMemory = Formatter.formatFileSize(this, totalBlocks * blockSize);
        // 可用空间
        String availableMemory = Formatter.formatFileSize(this, availableBlocks * blockSize);

        return "总空间: " + totalMemory + "\t可用空间: " + availableMemory + "\t:可用空间" + freeMemory;
    }

    /**
     * Activity跳转
     *
     * @param view
     */
    public void click(View view) {

        Intent intent = new Intent();
        switch (view.getId()) {
            case R.id.btn_SharedPreferences:
                intent.setClass(MainActivity.this, SharedPreferencesActivity.class);
                break;
        }
        startActivity(intent);
    }

    /**
     * 随app一起发布的原始数据库先放在assets文件中,在app第一次启动时通过io流操作存储到其他目录
     * 通过SharedPreferences存储数据库是否被转移的状态
     *
     * @param view
     */
    public void jump2AssetsSQLiteDataBase(View view) {
        mSharedPreferences = getSharedPreferences("dataBaseLoaded", MODE_PRIVATE);
        boolean loaded = mSharedPreferences.getBoolean("loaded", false);
        if (!loaded) {
            //没有加载数据库
            //开启子线程操作数据库
            new Thread() {
                @Override
                public void run() {
                    try {
                        loadDataBaseFromAssets();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }.start();
        } else {
            Log.i("MainActivity", "---jump2AssetsSQLiteDataBase()--->" + "数据库已经加载");
            //已经加载直接跳转
            Intent intent = new Intent(this, SQLiteOpenDataBaseActivity.class);
            startActivity(intent);
        }
    }

    private void loadDataBaseFromAssets() throws IOException {
        AssetManager assetManager = getResources().getAssets();
        //通过assetManager.open(String fileName)打开assets下文件
        InputStream inputStream = assetManager.open("database/android_manual.db");
        //获得目标目录/storage/emulated/0/Android/data/包名/files/Documents
        File file = getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS);
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(file,
                "android_manual.db")));
        BufferedInputStream bis = new BufferedInputStream(inputStream);
        byte[] bytes = new byte[1024 * 8];
        int len = 0;
        while ((len = bis.read(bytes)) != -1) {
            bos.write(bytes, 0, len);
        }
        bos.flush();
        //关流释放资源
        if (bis != null) {
            bis.close();
        }
        if (bos != null) {
            bos.close();
        }
        //修改SharedPreferences的状态
        SharedPreferences.Editor editor = mSharedPreferences.edit();
        editor.putBoolean("loaded", true);
        editor.commit();
        Log.i("MainActivity", "---loadDataBaseFromAssets()--->" + "数据库迁移成功");
        Intent intent = new Intent(this, SQLiteOpenDataBaseActivity.class);
        startActivity(intent);
    }

    public void jump2SQLiteOpenHelper(View view) {
        startActivity(new Intent(this, SQLiteOpenHelperActivity.class));
    }

    public void jump2AsyncTaskLoader(View view) {
        startActivity(new Intent(this, AsyncTaskLoaderActivity.class));
    }

    public void jump2CursorLoader(View view) {
        Log.i("MainActivity", "---jump2CursorLoader()--->");
        startActivity(new Intent(this, CursorLoaderActivity.class));

    }


    public void jump2ViewBinder(View view) {
        startActivity(new Intent(this, ViewBinderActivity.class));
    }
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//内部存储和外部存储的区别:
//  1.内部存储不需要任何权限;
//  2.内部存储的文件会伴随着app的卸载而被删除,外部存储不会
//  3.存储位置不同
//  4.调用方法不同:内部存储使用context.getXXX()调用,外部存储一般使用Environment.getXXX()调用
////////////////////////////////////////////////////////////////////////////////////////////////////